# -*- coding: utf-8 -*-
# created on 2016/12/28

from sympy import oo, solveset
from mathsolver.functions.base import *
from mathsolver.functions.hanshu.helper import check_func
from mathsolver.functions.hanshu.zhiyu import HanShuZhiYu


def logfunc_zhiyu_r(expr):
    """hs099.对数函数值域为R的定义
    :param expr log(f(x), a)
    """
    var = default_symbol(expr)
    logfx = expr.as_independent(var)[1]
    fx = logfx.args[0]
    fx_zhiyu = HanShuZhiYu().solver(BaseEq(['y', fx])).output[0].value
    qujian = Interval(0, oo)

    step1 = "求出 %s 的值域为 %s" % (fx, fx_zhiyu)
    step2 = "对数函数 %s 的值域为 R，即 %s ⊆ %s" % (expr, qujian, fx_zhiyu)
    return fx_zhiyu, (step1, step2)


class DuiShuHanShuZhiYuQiuCan(BaseFunction):
    """对数函数值域为R求参数"""

    def solver(self, *args):
        func = check_func(args[0])
        expr, var = func.expression, func.var
        canshu = expr.free_symbols - {var}
        canshu = canshu.pop()

        # 对数函数值域为R的定义
        # TODO: 考虑含参数值域，输出为分段值域，需要讨论
        fx_zhiyu, (step1, step2) = logfunc_zhiyu_r(expr)
        self.steps = [["", step1], ["", step2]]

        # 解 (0, oo) ⊆ fx_zhiyu
        # 如果是 Union， 只考虑右端点是 oo 的区间
        if fx_zhiyu.func is Union:
            fx_zhiyu2 = [item for item in fx_zhiyu.args if item.args[1] == oo]
            fx_zhiyu = fx_zhiyu2[0]

        assert fx_zhiyu._sup == oo

        res = solveset(fx_zhiyu._inf <= 0, domain=S.Reals)

        # log(f(x), m), m > 0
        logfx = expr.as_independent(var)[1]
        self.steps.append(["", "解出 %s ∈ %s" % (canshu, res)])
        logm = logfx / expr
        if logm.has(canshu):
            canshu_dingyi = solveset(logm.args[0] > 0, domain=S.Reals)
            res = res.intersect(canshu_dingyi)
            self.steps.append(["", "根据对数函数的定义可知 %s > 0，解得 %s ∈ %s" % (logm.args[0], canshu, canshu_dingyi)])
            self.steps.append(["", "综上，%s 的取值范围为 %s" % (canshu, res)])

        self.output.append(BaseValue(res))
        self.label.add("对数函数值域为R求参数")
        return self


if __name__ == '__main__':
    pass
